package org.ricks.condition2;

import org.ricks.condition2.event.ConditionCompletedEvent;
import org.ricks.condition2.event.PlayerAwareEvent;
import org.ricks.ioc.event.EventBus;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class CompositeCondition implements Condition {

    private final String playerId;
    private final List<Condition> children;
    private final Predicate<List<Condition>> completePredicate;

    public CompositeCondition(String playerId, List<Condition> conditions, Predicate<List<Condition>> predicate) {
        this.playerId = playerId;
        this.children = new CopyOnWriteArrayList<>(conditions);
        this.completePredicate = predicate;
    }

    @Override
    public void emit(PlayerAwareEvent event) {
        children.parallelStream() // 使用并行流提高处理效率
                .filter(c -> !c.isDone())
                .forEach(c -> c.emit(event));
    }

    @Override
    public boolean isDone() {
        boolean checkDone =  completePredicate.test(children);
        if(checkDone) {
            EventBus.post(new ConditionCompletedEvent(this, playerId));
            ConditionManager.ME().unregister(this); // 自动注销
        }
        return checkDone;
    }

    @Override
    public String getPlayerId() {
        return playerId;
    }

    @Override
    public Collection<Class<? extends PlayerAwareEvent>> getInterestedEventTypes() {
        return children.stream()
                .flatMap(c -> c.getInterestedEventTypes().stream())
                .distinct()
                .collect(Collectors.toList());
    }

    public void addCondition(Condition condition) {
        children.add(condition);
        // 自动刷新事件订阅
        if (checkEventTypesChanged()) {
            ConditionManager.ME().register(this);
        }
    }

    public void removeCondition(Condition condition) {
        children.remove(condition);
    }
}
